package com.kede.api.order.service.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.RandomUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.kede.api.order.controller.po.CreateLeeScorePo;
import com.kede.api.order.controller.po.GoodsNumPo;
import com.kede.api.order.pojo.LineEnum;
import com.kede.api.order.service.ILessScoreOrderService;
import com.kede.dictenum.BoolDictEnum;
import com.kede.domain.*;
import com.kede.ienum.PayTypeEnum;
import com.kede.ienum.order.OrderStatusEnum;
import com.kede.ienum.order.PayStatusEnum;
import com.kede.pojo.ResHttp;
import com.kede.service.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/***
 ** @Author:Pr.li
 ** @Description:
 ** @Date: create in 2023/5/15 14:23
 ***/
@Service
@Slf4j
public class LessScoreOrderServiceImpl implements ILessScoreOrderService {

    @Resource
    private UsersService usersService;

    @Resource
    private LeescoreAddressService addressService;

    @Resource
    private LeescoreGoodsService goodsService;

    @Resource
    private LeescoreOrderGoodsService orderGoodsService;

    @Resource
    private LeescoreOrderService orderService;

    @Resource
    private UserScoreLogService userScoreLogService;


    private BigDecimal zeno = new BigDecimal("0.00");
    //默认最大运费
    private BigDecimal maxExpressPrice = new BigDecimal("7.00");
    //默认未付款订单最大的等待时间 单位 秒
    private static final int orderwaittime = 60 * 15;


    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResHttp createLeeScoreOrder(CreateLeeScorePo createLeeScorePo) {
        UsersDomain users = usersService.getById(createLeeScorePo.getUserId());
        List<LeescoreOrderGoodsDomain> goodsDomainList = new ArrayList<>();
        //需要支付的钱
        BigDecimal paymoney = zeno;
        //商品的总价值
        BigDecimal totalScore = zeno;
        //运费
        BigDecimal expressPrice = zeno;
        boolean isOffline = true;
        //循环商品
        for (GoodsNumPo goodsNumPo : createLeeScorePo.getGoodsNumPos()) {
            LeescoreGoodsDomain goods = goodsService.getById(goodsNumPo.getGoodId());
            if(goods.getStock().compareTo(goodsNumPo.getNum()) < 0){
                return ResHttp.code(204,"库存不足");
            }
            //减库存
            goods.setStock(goods.getStock() - goodsNumPo.getNum());
            goodsService.updateById(goods);
            //加商品德币价格
            totalScore = totalScore.add(goods.getScoreprice().multiply(new BigDecimal(goodsNumPo.getNum().toString())));
            //加商品人民币价格
            if(goods.getMoney() != null && goods.getMoney().compareTo(zeno) > 0){
                paymoney = paymoney.add(goods.getMoney().multiply(new BigDecimal(goodsNumPo.getNum().toString())));
            }
            //加运费
            if(goods.getExpressPrice().compareTo(zeno) > 0){
                expressPrice = expressPrice.add(goods.getExpressPrice());
            }

            //创建订单商品信息
            LeescoreOrderGoodsDomain leescoreOrderGoodsDomain = LeescoreOrderGoodsDomain.builder().goodsId(goodsNumPo.getGoodId()).buyNum(goodsNumPo.getNum()).score(goods.getScoreprice())
                    .money(goods.getMoney()).goodsName(goods.getName()).goodsThumb(goods.getThumb()).sourceChannel(goods.getSourceChannel())
                    .typeInfo(goodsNumPo.getTypeInfo()).userId(users.getId()).build();
            //这里默认先设置付款后的状态，  如果未付款则在后面代码 统一设置没付款的状态
            if (goods.getSourceChannel().getCode().equals(LineEnum.OFFLINE.getCode())) {
                leescoreOrderGoodsDomain.setOrderStatus(OrderStatusEnum.OFFLINERECEIVE);
            }else {
                leescoreOrderGoodsDomain.setOrderStatus(OrderStatusEnum.SEND);
                isOffline = false;
            }
            goodsDomainList.add(leescoreOrderGoodsDomain);

        };
        if (expressPrice.compareTo(maxExpressPrice) > 0){
            expressPrice = maxExpressPrice;
        }
        //付款的时候再加上运费
        paymoney = paymoney.add(expressPrice);
        //去创建订单
        String orderNo = OrderRandomNo();
        LeescoreOrderDomain.LeescoreOrderDomainBuilder leescoreOrderDomainBuilder = LeescoreOrderDomain.builder()
                .orderId(orderNo)
                .other(createLeeScorePo.getOther())
                .uid(createLeeScorePo.getUserId())
                .addressId(createLeeScorePo.getAddressId());

        if (users.getIntegral().compareTo(totalScore) < 0){
            //用户积分不足，用RMB来补充 10德币=1RMB
            paymoney= paymoney.add(totalScore.subtract(users.getIntegral()).divide(new BigDecimal("10")));
            //现在不考虑优惠券 所以总价格等于实际支付价格
            leescoreOrderDomainBuilder
                    .tradeScore(users.getIntegral())
                    .scoreTotal(users.getIntegral());
            users.setIntegral(zeno);
        }else {
            leescoreOrderDomainBuilder
                    .tradeScore(totalScore)
                    .scoreTotal(totalScore);
            users.setIntegral(users.getIntegral().subtract(totalScore));
        }
        if (paymoney.compareTo(zeno) > 0){
            Long l = LocalDateTime.now().plusSeconds(orderwaittime).toEpochSecond(ZoneOffset.ofHours(8));
            leescoreOrderDomainBuilder.pay(PayStatusEnum.NOPAY)
                    .effectTime(l.intValue())
                    .paytype(PayTypeEnum.MINXI)
            .status(OrderStatusEnum.NOPAY);
        }else {
            leescoreOrderDomainBuilder.pay(PayStatusEnum.PAY).paytype(PayTypeEnum.SCORE);
            if(isOffline){ //都是线下单
                leescoreOrderDomainBuilder.status(OrderStatusEnum.OFFLINERECEIVE);
            }else {
                //有线下和线上
                leescoreOrderDomainBuilder.status(OrderStatusEnum.SEND);
            }
        }
        leescoreOrderDomainBuilder.moneyTotal(paymoney).tradeMoney(paymoney).isdel(0);
        LeescoreOrderDomain order = leescoreOrderDomainBuilder.build();
        orderService.save(order);
        Integer orderId = order.getId();
        goodsDomainList.forEach(leescoreOrderGoodsDomain -> {
            switch (order.getStatus()){
                case OFFLINERECEIVE:
                    leescoreOrderGoodsDomain.setOrderStatus(OrderStatusEnum.OFFLINERECEIVE);
                    break;
                case NOPAY:
                    leescoreOrderGoodsDomain.setOrderStatus(OrderStatusEnum.NOPAY);
                    break;
            }
            leescoreOrderGoodsDomain.setOrderId(orderId);
            orderGoodsService.save(leescoreOrderGoodsDomain);
        });
        Map data = new HashMap();
        //告诉前端去支付
        if (paymoney.compareTo(zeno) > 0){
            //与php一致
//            data.put("code",1);
            data.put("order_sn",orderNo);
            data.put("money",paymoney);
            return ResHttp.set(205,"去支付",data);
        }else {
            //更新用户德币
            usersService.updateById(users);
            //添加记录
            UserScoreLogDomain scoreLogDomain = UserScoreLogDomain.builder()
                    .after(users.getIntegral())
                    .before(users.getIntegral().add(totalScore))
                    .userId(users.getId())
                    .score(new BigDecimal("-" + totalScore.toString()))
                    .changeType(2)//与php 一致
                    .memo("消费德币兑换商品").build();
            userScoreLogService.save(scoreLogDomain);
        }
        return ResHttp.ok();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResHttp receiveOrder(Integer orderid, Integer userid) {
        LeescoreOrderDomain byId = orderService.getById(orderid);
        if (byId==null){
            return ResHttp.failMsg("订单不存在");
        }
        byId.setStatus(OrderStatusEnum.FINISH);
        orderService.updateById(byId);
        LambdaQueryWrapper<LeescoreOrderGoodsDomain> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(LeescoreOrderGoodsDomain::getOrderId,orderid);
        List<LeescoreOrderGoodsDomain> list = orderGoodsService.list(queryWrapper);
        for (LeescoreOrderGoodsDomain orderGoodsDomain : list) {
            orderGoodsDomain.setOrderStatus(OrderStatusEnum.FINISH);
            orderGoodsService.updateById(orderGoodsDomain);
        }
        return ResHttp.ok();
    }

    @Override
    public void deleteOrder(Integer orderId) {
        LeescoreOrderDomain byId = orderService.getById(orderId);
        if (byId.getStatus().getCode().equals(OrderStatusEnum.FINISH.getCode())||byId.getStatus().getCode().equals(OrderStatusEnum.CANCEL.getCode())){
            byId.setIsdel(BoolDictEnum.TRUE.getCode());
            orderService.updateById(byId);
        }else{
            throw new RuntimeException("只有已完成/已取消的订单可以删除");
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void backOneOrderById(Integer orderId) {
        log.debug("主动调用取消订单");
        LeescoreOrderDomain byId = orderService.getById(orderId);
        byId.setEffectTime(0);
        byId.setStatus(OrderStatusEnum.CANCEL);
        orderService.updateById(byId);
        orderGoodsService.backOrderGoodsByOrderId(orderId);
    }



    public static String OrderRandomNo(){
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder
                .append("JF")//不要改php的支付回调对这个开头的订单有处理
                .append(DateUtil.format(LocalDateTime.now(), "yyyyMMddHHmm"))
                .append(RandomUtil.randomNumbers(4));
        return stringBuilder.toString();
    }

}
